package com.wdb.common.configurer.subject;

import com.wdb.common.constant.Constant;
import com.wdb.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;
import java.util.Objects;

public class SubjectContextInterceptor extends HandlerInterceptorAdapter {
    private String proxy_target;

    private String proxy_subject;

    private static final String REQUEST_TIME = "reqtime";

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            // 获取当前系统时间 - 便于日志跟踪

            long reqtime = System.currentTimeMillis();

            // 获取请求头目标 - 此处指代用户主键类型

            String target = request.getHeader(proxy_target);

            // 获取请求头主体 - 此处指代用户主键

            String subject = request.getHeader(proxy_subject);

            // 日志输出请求时间 - 请求路径

            String uri = request.getRequestURI();

            if (logger.isDebugEnabled()) {
                logger.info("[{}] - uri        - [{}]", reqtime, uri);
            }

            // 校验 - 请求主体和请求目标

            String t = SubjectTarget.INVOKE.toString();

            Long s = Constant.Context.Subject.INVOKE;

            if (StringUtils.isNotEmpty(target)) {
                t = new String(Base64.getDecoder().decode(target));
            }

            if (Objects.nonNull(subject)) {
                s = Long.parseLong(new String(Base64.getDecoder().decode(subject)));
            }

            // 请求主体和请求目标线程本地化

            SubjectContext.setTarget(t);

            SubjectContext.setSubject(s);

            SubjectContext.set(REQUEST_TIME, reqtime);

            // 日志输出请求头主体和目标

            if (logger.isDebugEnabled()) {
                logger.info("[{}] - target     - [{}] ", reqtime, t);
                logger.info("[{}] - subject    - [{}] ", reqtime, s);
            }
        }

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        String target = SubjectContext.getTarget();

        Long subject = SubjectContext.getSubject();

        if (StringUtils.isNotEmpty(target) && Objects.nonNull(subject)) {
            long reqtime = (long) SubjectContext.get(REQUEST_TIME);

            SubjectContext.remove();

            // 销毁线程本地化变量

            if (logger.isDebugEnabled()) {
                logger.info("[{}] - invalidate - [{}]", reqtime, request.getRequestURI());
            }
        }
    }

    public void setProxy_target(String proxy_target) {
        this.proxy_target = proxy_target;
    }

    public void setProxy_subject(String proxy_subject) {
        this.proxy_subject = proxy_subject;
    }
}
